﻿// ImageProcessDlg.cpp: 实现文件
//

#include "pch.h"
#include "EmbossedPicture.h"
#include "afxdialogex.h"
#include "ImageProcessDlg.h"
#include "resource.h"
using namespace Gdiplus;


// CImageProcessDlg 对话框

IMPLEMENT_DYNAMIC(CImageProcessDlg, CDialogEx)

CImageProcessDlg::CImageProcessDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG_IMAGEPROCESS, pParent)
{
	m_enDrawType = DRAWTYPE::NORMAL;
}

CImageProcessDlg::~CImageProcessDlg()
{
}

void CImageProcessDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CImageProcessDlg, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_GRAVE, &CImageProcessDlg::OnBnClickedButtonGrave)
	ON_BN_CLICKED(IDC_BUTTON_RELIEF, &CImageProcessDlg::OnBnClickedButtonRelief)
	ON_WM_PAINT()
	ON_BN_CLICKED(IDC_BUTTON_NORMAL, &CImageProcessDlg::OnBnClickedButtonNormal)
	ON_BN_CLICKED(IDC_BUTTON_FILTER, &CImageProcessDlg::OnBnClickedButtonFilter)
	ON_BN_CLICKED(IDC_BUTTON_OILPAINT, &CImageProcessDlg::OnBnClickedButtonOilpaint)
	ON_BN_CLICKED(IDC_BUTTON_WOODCUT, &CImageProcessDlg::OnBnClickedButtonWoodcut)
	ON_BN_CLICKED(IDC_BUTTON_STRONGLIGHT, &CImageProcessDlg::OnBnClickedButtonStronglight)
	ON_BN_CLICKED(IDC_BUTTON_SOFTEN, &CImageProcessDlg::OnBnClickedButtonSoften)
	ON_BN_CLICKED(IDC_BUTTON_SHARPING, &CImageProcessDlg::OnBnClickedButtonSharping)
END_MESSAGE_MAP()


// CImageProcessDlg 消息处理程序


void CImageProcessDlg::OnBnClickedButtonGrave()
{
	// TODO: 在此添加控件通知处理程序代码

	m_enDrawType = DRAWTYPE::GRAVE;
	Invalidate();

}


void CImageProcessDlg::OnBnClickedButtonRelief()
{
	// TODO: 在此添加控件通知处理程序代码
	m_enDrawType = DRAWTYPE::RELIEF;
	Invalidate();
}


BOOL CImageProcessDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	



	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}


void CImageProcessDlg::OnPaint()
{
	CPaintDC dc(this); // device context for painting
					   // TODO: 在此处添加消息处理程序代码
					   // 不为绘图消息调用 CDialogEx::OnPaint()
					   // CRect rect;
	CRect rect;
	GetDlgItem(IDC_STATIC_PICTURE)->GetWindowRect(&rect);
	ScreenToClient(&rect);
	Gdiplus::Graphics graphics(dc.m_hDC); // Create a GDI+ graphics object
	CBitmap bmp;
	bmp.LoadBitmapW(IDB_BMP_MYLOVE);
	CPalette palette;
	palette.CreateHalftonePalette(&dc);
	Gdiplus::Bitmap image((HBITMAP)bmp, (HPALETTE)palette); // Construct an image	
	int nWidth = image.GetWidth();
	int nHeight = image.GetHeight();
	// 第二种方式
	switch (m_enDrawType)
	{
	case DRAWTYPE::NORMAL:
	{
		graphics.DrawImage(&image, Gdiplus::Rect(rect.left,rect.top,rect.Width(),rect.Height()),0,0,image.GetWidth(),image.GetHeight(),Gdiplus::UnitPixel);
		DeleteDC(dc.m_hDC);
	}
	break;
	case DRAWTYPE::GRAVE:
	{
	
		Gdiplus::Color color,colorLeft,colorTemp;
		for (int i = nWidth; i > 0; i--)
		{
			for (int j= nHeight;j>0;j--)
			{
				image.GetPixel(i,j, &color);
				image.GetPixel(i-1, j-1, &colorLeft);

				float dbR = max(67,min(255,abs(color.GetRed() - colorLeft.GetRed()+128)));
				float dbG = max(67, min(255, abs(color.GetGreen() - colorLeft.GetGreen() + 128)));
				float dbB = max(67, min(255, abs(color.GetBlue() - colorLeft.GetBlue() + 128)));

				colorTemp.SetValue(color.MakeARGB(255, dbR, dbG, dbB));

				image.SetPixel(i,j,colorTemp);
			}	
		}
		graphics.DrawImage(&image, Rect(rect.left, rect.top, rect.Width(), rect.Height()));
		DeleteDC(dc.m_hDC);
	}
	break;
	case DRAWTYPE::RELIEF:
	{
		Gdiplus::Color color, colorLeft, colorTemp;
		for (int i = 0; i < nHeight; i++)
		{
			for (int j = 0; j < nWidth-1; j++)
			{
				image.GetPixel(j, i, &color);
				image.GetPixel(j + 1, i + 1, &colorLeft);

				float dbR = max(67, min(255, abs(color.GetRed() - colorLeft.GetRed() + 128)));
				float dbG = max(67, min(255, abs(color.GetGreen() - colorLeft.GetGreen() + 128)));
				float dbB = max(67, min(255, abs(color.GetBlue() - colorLeft.GetBlue() + 128)));

				colorTemp.SetValue(color.MakeARGB(255, dbR, dbG, dbB));

				image.SetPixel(j,i,colorTemp);
			}	
		}
		graphics.DrawImage(&image, Rect(rect.left, rect.top, rect.Width(), rect.Height()));
		DeleteDC(dc.m_hDC);
	}
	break;
	case DRAWTYPE::FILTER:
	{
		Gdiplus::Color color, colorLeft, colorTemp;
		for (int i = 0; i < nHeight; i++)
		{
			for (int j = 0; j < nWidth - 1; j++)
			{
				image.GetPixel(j, i, &color);
				float dbR = 255 - color.GetRed();
				float dbG = 255 - color.GetGreen();
				float dbB = 255 - color.GetBlue();
				colorTemp.SetValue(color.MakeARGB(255, dbR, dbG, dbB));
				image.SetPixel(j, i, colorTemp);
			}
		}
		graphics.DrawImage(&image, Rect(rect.left, rect.top, rect.Width(), rect.Height()));
		DeleteDC(dc.m_hDC);
	}
	break;
	case DRAWTYPE::OILPAINT:
	{
		int nAvg = 0;
		srand((unsigned)time(NULL));
		Gdiplus::Color color, colorLeft, colorTemp;
		for (int i = 0; i < nWidth-5; i++)
		{
			for (int j = 0; j < nHeight - 3; j++)
			{
				int n = rand() % 5;
				image.GetPixel(i+ n, j+n, &color);
				image.SetPixel(i, j, color);
			}
		}
		graphics.DrawImage(&image, Rect(rect.left, rect.top, rect.Width(), rect.Height()));
		DeleteDC(dc.m_hDC);
	}
	break;
	case DRAWTYPE::WOODCUT:
	{
		int nTmp = 0;
		Gdiplus::Color color, colorLeft, colorTemp;
		for (int i = 0; i < nWidth; i++)
		{
			for (int j = 0; j < nHeight; j++)
			{
				int  nAvg = 0;
				image.GetPixel(j, i, &color);
				nAvg = (color.GetRed() + color.GetGreen() + color.GetBlue())/3;
				if (nAvg >= 128)
					nTmp = 255;
				else
					nTmp = 0;
				
				colorTemp.SetValue(color.MakeARGB(255, nTmp, nTmp, nTmp));
				image.SetPixel(i,j,colorTemp);
			}
		}
		graphics.DrawImage(&image, Rect(rect.left, rect.top, rect.Width(), rect.Height()));
		DeleteDC(dc.m_hDC);
	}
	break;
	case DRAWTYPE::STRONG_LIGHT:
	{
		int nA = nWidth / 2;
		int nB = nHeight / 2;
		CPoint Centerpt(nA, nB);
		int nRadius = 100;
		Gdiplus::Color color, colorLeft, colorTemp;
		for (int i = 0; i < nWidth; i++)
		{
			for (int j = 0; j < nHeight; j++)
			{
				CPoint pt(i,j);
				if (Distance(pt, Centerpt) < nRadius)
				{
					
					image.GetPixel(i, j, &color);
					float dbR = 0.0, dbG = 0.0,dbB = 0.0;
					dbR = color.GetRed() + 220 * (1 - Distance(pt, Centerpt)/ nRadius);
					dbR = max(0,min(dbR,255));
					dbG = color.GetGreen() + 220 * (1 - Distance(pt, Centerpt) / nRadius);
					dbG = max(0, min(dbG, 255));
					dbB = color.GetBlue() + 220 * (1 - Distance(pt, Centerpt) / nRadius);
					dbB = max(0, min(dbB, 255));

					colorTemp.SetValue(color.MakeARGB(255, dbR, dbG, dbB));
					image.SetPixel(i, j, colorTemp);
				}
			}
		}
		graphics.DrawImage(&image, Rect(rect.left, rect.top, rect.Width(), rect.Height()));
		DeleteDC(dc.m_hDC);
	}
	break;
	case DRAWTYPE::SOFTEN:
	{
		Gdiplus::Color color[3][3], color2, colorTemp;
		for (int i = 1; i < nWidth-2; i++)
		{
			for (int j = 1; j < nHeight-2; j++)
			{
				image.GetPixel(i-1, j-1, &color[0][0]);
				image.GetPixel(i - 1, j, &color[0][1]);
				image.GetPixel(i - 1, j+1, &color[0][2]);

				image.GetPixel(i, j - 1, &color[1][0]);
				image.GetPixel(i, j, &color[1][1]);
				image.GetPixel(i, j + 1, &color[1][2]);

				image.GetPixel(i+1, j - 1, &color[2][0]);
				image.GetPixel(i+1, j, &color[2][1]);
				image.GetPixel(i+1, j + 1, &color[2][2]);

				int nRSum = 0;
				int nGSum = 0;
				int nBSum = 0;

				for (int m = 0; m < 3; m++)
				{
					for (int n = 0; n < 3; n++)
					{
						nRSum += color[m][n].GetRed();
						nGSum += color[m][n].GetGreen();
						nBSum += color[m][n].GetBlue();
					}
				}
				colorTemp.SetValue(color2.MakeARGB(255, (float)(nRSum/9), (float)(nGSum / 9), (float)(nBSum / 9)));
				image.SetPixel(i, j, colorTemp);
				
			}
		}
		graphics.DrawImage(&image, Rect(rect.left, rect.top, rect.Width(), rect.Height()));
		DeleteDC(dc.m_hDC);
	}
	break;
	case DRAWTYPE::SHARPING:
	{
		Gdiplus::Color colorLeft, color3, colorNow, colorTemp;
		float dbDep = 0.990f;
		for (int i = 1; i < nWidth - 1; i++)
		{
			for (int j = 1; j < nHeight - 1; j++)
			{
				image.GetPixel(i, j, &colorNow);
				image.GetPixel(i - 1, j-1, &colorLeft);

				float dbR = colorNow.GetRed() + (colorNow.GetRed() - colorLeft.GetRed() * dbDep);
				dbR = min(255,max(0, dbR));
				float dbG = colorNow.GetGreen() + (colorNow.GetGreen() - colorLeft.GetGreen() * dbDep);
				dbG = min(255, max(0, dbG));
				float dbB = colorNow.GetBlue() + (colorNow.GetBlue() - colorLeft.GetBlue() * dbDep);
				dbB = min(255, max(0, dbB));

				colorTemp.SetValue(color3.MakeARGB(255, dbR, dbG, dbB));
				image.SetPixel(i, j, colorTemp);

			}
		}
		graphics.DrawImage(&image, Rect(rect.left, rect.top, rect.Width(), rect.Height()));
		DeleteDC(dc.m_hDC);
	}
	break;
	}
}


void CImageProcessDlg::OnBnClickedButtonNormal()
{
	// TODO: 在此添加控件通知处理程序代码
	m_enDrawType = DRAWTYPE::NORMAL;
	Invalidate();
}


void CImageProcessDlg::OnBnClickedButtonFilter()
{
	// TODO: 在此添加控件通知处理程序代码
	m_enDrawType = DRAWTYPE::FILTER;
	Invalidate();
}


void CImageProcessDlg::OnBnClickedButtonOilpaint()
{
	// TODO: 在此添加控件通知处理程序代码
	m_enDrawType = DRAWTYPE::OILPAINT;
	Invalidate();
}


void CImageProcessDlg::OnBnClickedButtonWoodcut()
{
	// TODO: 在此添加控件通知处理程序代码
	m_enDrawType = DRAWTYPE::WOODCUT;
	Invalidate();
}


void CImageProcessDlg::OnBnClickedButtonStronglight()
{
	// TODO: 在此添加控件通知处理程序代码
	m_enDrawType = DRAWTYPE::STRONG_LIGHT;
	Invalidate();
	
}

float CImageProcessDlg::Distance(CPoint ptA, CPoint ptB)
{
	float dbI = pow((ptA.x - ptB.x), 2) + pow((ptA.y - ptB.y),2);
	return sqrt(dbI);
}

void CImageProcessDlg::OnBnClickedButtonSoften()
{
	// TODO: 在此添加控件通知处理程序代码
	m_enDrawType = DRAWTYPE::SOFTEN;
	Invalidate();
}


void CImageProcessDlg::OnBnClickedButtonSharping()
{
	// TODO: 在此添加控件通知处理程序代码
	m_enDrawType = DRAWTYPE::SHARPING;
	Invalidate();
}
